use crate::config::BinanceConfig;
use crate::errors::Result;
use crate::rest::RestClient;
use crate::websocket::WebSocketClient;
use std::sync::Arc;

/// 统一的Binance客户端
pub struct BinanceClient {
    config: Arc<BinanceConfig>,
    rest_client: RestClient,
    ws_client: Option<WebSocketClient>,
}

impl BinanceClient {
    /// 创建新的客户端
    pub fn new(config: BinanceConfig) -> Result<Self> {
        let config = Arc::new(config);
        let rest_client = RestClient::new(config.clone())?;
        
        Ok(Self {
            config,
            rest_client,
            ws_client: None,
        })
    }

    /// 获取REST客户端
    pub fn rest(&self) -> &RestClient {
        &self.rest_client
    }

    /// 获取WebSocket客户端
    pub fn websocket(&mut self) -> Result<&mut WebSocketClient> {
        if self.ws_client.is_none() {
            self.ws_client = Some(WebSocketClient::new(self.config.clone())?);
        }
        Ok(self.ws_client.as_mut().unwrap())
    }

    /// 获取配置
    pub fn config(&self) -> &BinanceConfig {
        &self.config
    }

    /// 更新配置
    pub fn update_config(&mut self, config: BinanceConfig) -> Result<()> {
        self.config = Arc::new(config);
        self.rest_client = RestClient::new(self.config.clone())?;
        self.ws_client = None; // 重置WebSocket客户端
        Ok(())
    }
}

/// 客户端构建器
pub struct BinanceClientBuilder {
    config: BinanceConfig,
}

impl BinanceClientBuilder {
    pub fn new(api_key: String, secret_key: String, product_type: crate::ProductType) -> Self {
        Self {
            config: BinanceConfig::new(api_key, secret_key, product_type),
        }
    }

    pub fn environment(mut self, env: crate::Environment) -> Self {
        self.config.environment = env;
        self
    }

    pub fn proxy(mut self, http_proxy: Option<String>, ws_proxy: Option<String>) -> Self {
        self.config.http_proxy = http_proxy;
        self.config.ws_proxy = ws_proxy;
        self
    }

    pub fn timeout(mut self, timeout_seconds: u64) -> Self {
        self.config.timeout_seconds = timeout_seconds;
        self
    }

    pub fn retry_count(mut self, retry_count: u32) -> Self {
        self.config.retry_count = retry_count;
        self
    }

    pub fn build(self) -> Result<BinanceClient> {
        // 打印配置信息
        tracing::info!("[CLIENT] 构建Binance客户端");
        tracing::info!("[CLIENT] 产品类型: {:?}", self.config.product_type);
        tracing::info!("[CLIENT] 环境: {:?}", self.config.environment);
        tracing::info!("[CLIENT] REST URL: {}", self.config.rest_base_url());
        tracing::info!("[CLIENT] WebSocket URL: {}", self.config.ws_base_url());
        tracing::info!("[CLIENT] API前缀: {}", self.config.product_type.base_api_prefix());
        
        BinanceClient::new(self.config)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{Environment, ProductType};

    #[test]
    fn test_client_creation() {
        let config = BinanceConfig::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::Spot,
        );
        
        let client = BinanceClient::new(config);
        assert!(client.is_ok());
    }

    #[test]
    fn test_client_builder() {
        let client = BinanceClientBuilder::new(
            "test_api_key".to_string(),
            "test_secret_key".to_string(),
            ProductType::UsdM,
        )
        .environment(Environment::Demo)
        .timeout(60)
        .build();
        
        assert!(client.is_ok());
    }
}
